/*
 * rc rulecheck with ast
 */

%code requires {
#include <stdio.h>
typedef void* yyscan_t;
}


%union {
  struct ast *a;
  int opbit;
  long n;
  double d;
  char* s;
  bool b;
}


%param {yyscan_t yyscanner}
%parse-param {struct ast **a}
%define api.pure full
%locations
%{
#define YY_DECL int yylex \
               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
extern YY_DECL;
#include "rc.routine.h"
%}

%printer { yyoutput << $$; } <*>;

%token <n> NUMBER 
%token <s> NAME STRING
%token <d> FLOAT
%token EOL
%token IF ELSE ELIF RETURN 

%left OR 
%left AND NAND
%left NOT 
%nonassoc <opbit> CMP

%type <a> factor explist
%start rule
%%
rule : %empty { *a = NULL;}
  | factor { *a = $1;}
;
factor : factor CMP factor { $$ = newast($2, $1,$3);$$->pos = @2.last_column;}
  | factor OR factor { $$ = newast(ntype_or, $1,$3);$$->pos = @2.last_column;}
  | factor AND factor { $$ = newast(ntype_and, $1,$3);$$->pos = @2.last_column;}
  | factor NAND factor { $$ = newast(ntype_nand, $1,$3);$$->pos = @2.last_column;}
  | NOT factor { $$ = newast(ntype_not, $2,NULL);$$->pos = @1.last_column;}
  | '(' factor ')'   { $$ = $2;$$->pos = @1.last_column;} /* literal */
  | NUMBER { $$ = newnum($1); $$->pos = @1.last_column;}
  | FLOAT { $$ = newfloat($1);$$->pos = @1.last_column;}
  | NAME   { $$ = newstr(ntype_name,$1);$$->pos = @1.last_column;} /* ref */
  | STRING { $$ = newstr(ntype_str,$1);$$->pos = @1.last_column;} /* literal */
  | NAME '(' explist ')'   { $$ = newfunc(ntype_fn,newstr(ntype_name,$1),$3);$$->pos = @1.last_column;} /* literal */
;
explist : factor  { $$ = newlist($1); $$->pos = @1.last_column;}
  | factor ',' explist { $$ = addtolist($3,$1);$$->pos = @1.last_column;}

%%
